package io.renren.wechat.controller;

import io.renren.common.utils.R;
import io.renren.wechat.service.JSAPITicketService;
import io.renren.wechat.service.SignService;
import io.renren.wechat.support.WXPayUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author dmcp@qq.com
 * @since 2021/12/2 00:07
 */
@RestController
@RequestMapping("/wechat/ticket")
public class TicketController {
    private static final Logger LOGGER = LoggerFactory.getLogger(TicketController.class);
    private JSAPITicketService jsapiTicketService;
    private SignService signService;

    @RequestMapping("/get")
    public R getTicket(@RequestParam(value = "corpId", required = false) String corpId,
                       @RequestParam(value = "type", required = false) String type) {
        if (StringUtils.isBlank(type)) {
            return R.error("type不能为空且只能为agent或corp");
        }
        if (StringUtils.equalsIgnoreCase(type, "agent") && StringUtils.isBlank(corpId)) {
            return R.error("corpId不能为空");
        }

        String ticketFromCache;
        if (StringUtils.equalsIgnoreCase(type, "agent")) {
            ticketFromCache = jsapiTicketService.getAgentTicket(corpId);
        } else if (StringUtils.equalsIgnoreCase(type, "corp")) {
            ticketFromCache = jsapiTicketService.getCorpTicket();
        } else {
            ticketFromCache = jsapiTicketService.getAgentTicket(corpId);
        }

        return R.ok().put("ticket", ticketFromCache);
    }

    /**
     * 1）签名用的noncestr和timestamp必须与wx.config中的nonceStr和timestamp相同。
     * 2）签名用的url必须是调用JS接口页面的完整URL。
     * 3）出于安全考虑，开发者必须在服务器端实现签名的逻辑。
     * <p>
     * 1. 字段值采用原始值，不要进行URL转义；
     * 2. 必须严格按照如下格式拼接，不可变动字段顺序。
     *
     * @param corpId corpId
     * @param url    current request url
     * @return sing map
     */
    @RequestMapping("/sign")
    public R sign(@RequestParam(value = "corpId", required = false) String corpId,
                  @RequestParam(value = "url", required = false) String url) {
        if (StringUtils.isBlank(url)) {
            return R.error("url不能为空");
        }
        if (StringUtils.isBlank(corpId)) {
            return R.error("corpId不能为空");
        }

        LOGGER.debug("calc sign input params, corpId: {}, url: {}", corpId, url);

        final String ticketFromCache = jsapiTicketService.getAgentTicket(corpId);
        final String nonceStr = WXPayUtil.generateNonceStr();
        final long currentTimestampLongValue = WXPayUtil.getCurrentTimestamp();
        final String currentTimestamp = String.valueOf(currentTimestampLongValue);// like 1414587457

        final String signature = signService.sign(url, currentTimestamp, nonceStr, ticketFromCache);

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("noncestr", nonceStr);
        resultMap.put("timestamp", currentTimestampLongValue);
        resultMap.put("url", url);
        resultMap.put("signature", signature);

        LOGGER.debug("result map: {}", resultMap);

        return R.ok(resultMap);
    }

    @Autowired
    public void setJsapiTicketService(JSAPITicketService jsapiTicketService) {
        this.jsapiTicketService = jsapiTicketService;
    }

    @Autowired
    public void setSignService(SignService signService) {
        this.signService = signService;
    }
}
